package o2o.thridpost.dada.controller;

import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import com.jinyou.utils.common.AjaxResult;
import com.jinyou.utils.common.ValidateUtil;
import lombok.extern.slf4j.Slf4j;
import o2o.cache.order.OrderInfoMemory;
import o2o.cache.order.OrderInfoPreMemory;
import o2o.config.PropConfigure;
import o2o.config.dao.UserDaoSql;
import o2o.config.redis.RedisManager;
import o2o.config.thirdpost.dada.DadaConfig;
import o2o.config.thirdpost.dada.DadaRequestClient;
import o2o.dao.PO.PojoTables;
import o2o.dao.PO.order.ORDER_STATUS;
import o2o.thridpost.dada.client.DadaApiResponse;
import o2o.thridpost.dada.client.DadaRequestParam;
import o2o.thridpost.dada.config.UrlConstant;
import o2o.thridpost.dada.model.to.AddDadaOrderTO;
import o2o.thridpost.dada.model.to.CancelDadaOrderTO;
import o2o.thridpost.dada.model.to.QueryDeliverFeeTO;
import o2o.thridpost.dada.model.to.UpdateDadaOrderTO;
import o2o.thridpost.dada.model.vo.QueryDeliverFeeVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;


/**
 * Created with IntelliJ IDEA.
 *
 * @author sunyufan deporation@qq.com
 * @date 2021/4/30 14:11
 * @description: DadaOrderController
 */
@RequestMapping("/dada/order")
@RestController
@Slf4j
public class DadaOrderController {

    @Autowired
    private DadaRequestClient requestClient;

    /**
     * 增加订单
     */
    @RequestMapping(value = "/addOrder", method = RequestMethod.POST)
    public String addOrderToDada(@RequestBody AddDadaOrderTO addDadaOrderTO) {
        log.info("接收参数:" + addDadaOrderTO);
        DadaRequestParam<AddDadaOrderTO> requestParam = new DadaRequestParam<>(addDadaOrderTO, requestClient.getAppConfig());

        DadaApiResponse apiResponse = requestClient.callRpc(requestParam, UrlConstant.ORDER_ADD_URL);

        log.info(apiResponse.toString());

        if (apiResponse.getCode() == 0) {
            return AjaxResult.successResult(apiResponse.getResult());
        } else if (apiResponse.getCode() == 2015) {
            return AjaxResult.errorResult("订单已经下发，请勿重复下单");
        } else {
            return AjaxResult.errorResult(apiResponse.getMsg());
        }
    }

    /**
     * 取消订单
     *
     * @param cancelDadaOrderTO 取消订单信息
     */
    @RequestMapping(value = "/cancelOrder", method = RequestMethod.POST)
    public String cancelOrder(@RequestBody CancelDadaOrderTO cancelDadaOrderTO) {

        log.info("接收参数:" + cancelDadaOrderTO);

        DadaRequestParam<CancelDadaOrderTO> requestParam = new DadaRequestParam<>(cancelDadaOrderTO, requestClient.getAppConfig());
        DadaApiResponse apiResponse = requestClient.callRpc(requestParam, UrlConstant.CANCEL_ORDER_URL);

        log.info(apiResponse.toString());

        if (apiResponse.getCode() == 0) {
            return AjaxResult.successResult(apiResponse.getResult());
        } else {
            return AjaxResult.errorResult("msg", apiResponse.getMsg());
        }
    }

    /**
     * 预查询订单的费用 生成deliveryNo 3分钟内有效 可以直接走下一个接口用deliveryNo来进行订单发布
     *
     * @param queryDeliverFeeTO 订单预查询
     */
    @RequestMapping(value = "/queryDeliverFee", method = RequestMethod.POST)
    public String queryDeliverOrder(@RequestBody QueryDeliverFeeTO queryDeliverFeeTO) {

        log.info("接收参数:" + queryDeliverFeeTO);

        DadaRequestParam<QueryDeliverFeeTO> requestParam = new DadaRequestParam<>(queryDeliverFeeTO, requestClient.getAppConfig());
        DadaApiResponse apiResponse = requestClient.callRpc(requestParam, UrlConstant.QUERY_DELIVER_FEE);

        log.info(apiResponse.getResult().toString());

        if (apiResponse.getCode() == 0) {
            QueryDeliverFeeVO queryDadaOrderVO = new Gson().fromJson(apiResponse.getResult().toString(), QueryDeliverFeeVO.class);
            RedisManager.set("QueryDeliverFeeTO:delivery_no:" + queryDadaOrderVO.getDeliveryNo(), new Gson().toJson(queryDeliverFeeTO), 3 * 60);
            return AjaxResult.successResult(apiResponse.getResult());
        } else {
            return AjaxResult.errorResult("msg", apiResponse.getMsg());
        }
    }

    /**
     * 订单预查询三分钟内，可以通过deliveryNo直接进行下单
     *
     * @param deliveryNo 订单编号
     */
    @RequestMapping(value = "/addAfterQuery", method = RequestMethod.GET)
    public String addAfterQuery(@RequestParam("deliveryNo") String deliveryNo) {

        Object cache = RedisManager.get("QueryDeliverFeeTO:delivery_no:" + deliveryNo);

        if (ValidateUtil.isNull(cache)) {
            return AjaxResult.errorResult("订单已经超时,请走正常发货接口或重新预发货");
        }

        Map<String, String> param = new HashMap<>(1);
        param.put("deliveryNo", deliveryNo);


        DadaRequestParam<Map<String, String>> requestParam = new DadaRequestParam<>(param, requestClient.getAppConfig());
        DadaApiResponse apiResponse = requestClient.callRpc(requestParam, UrlConstant.ADD_AFTER_QUERY);

        log.info(apiResponse.toString());
        if (apiResponse.getCode() == 0) {
            return AjaxResult.successResult(apiResponse.getResult());
        } else {
            return AjaxResult.errorResult("msg", apiResponse.getMsg());
        }
    }

    /**
     * 订单状态的查询
     *
     * @param orderId 订单id
     * @return 订单查询结果
     */
    @RequestMapping(value = "/queryOrder", method = RequestMethod.GET)
    public String queryOrder(@RequestParam("orderId") String orderId) {

        Map<String, String> param = new HashMap<>(1);
        param.put("order_id", orderId);

        DadaRequestParam<Map<String, String>> requestParam = new DadaRequestParam<>(param, requestClient.getAppConfig());

        DadaApiResponse apiResponse = requestClient.callRpc(requestParam, UrlConstant.QUERY_ORDER);

        log.info(apiResponse.toString());

        if (apiResponse.getCode() == 0) {
            return AjaxResult.successResult(apiResponse.getResult());
        } else {
            return AjaxResult.errorResult("msg", apiResponse.getMsg());
        }
    }

    /**
     * 重新派发达达订单
     *
     * @param addDadaOrderTO 添加信息
     * @return 添加结果
     */
    @RequestMapping(value = "/reAddOrder", method = RequestMethod.POST)
    public String reAddOrder(@RequestBody AddDadaOrderTO addDadaOrderTO) {
        DadaRequestParam<AddDadaOrderTO> dadaRequestParam = new DadaRequestParam<>(addDadaOrderTO, requestClient.getAppConfig());
        DadaApiResponse apiResponse = requestClient.callRpc(dadaRequestParam, UrlConstant.RE_ADD_ORDER_URL);
        log.info(apiResponse.toString());

        if (apiResponse.getCode() == 0) {
            return AjaxResult.successResult(apiResponse.getResult());
        } else {
            return AjaxResult.errorResult("msg", apiResponse.getMsg());
        }
    }

    /**
     * 投递异常物品返回确认
     *
     * @param orderId 订单id
     * @return 订单处理结果
     */
    @RequestMapping(value = "confirm", method = RequestMethod.GET)
    public String confirmGoods(@RequestParam("orderId") String orderId) {
        log.info("接受参数:" + orderId);

        StringBuffer sbPre = new StringBuffer();


        Map<String, String> param = new HashMap<>(1);
        param.put("order_id", orderId);

        DadaRequestParam<Map<String, String>> requestParam = new DadaRequestParam<>(param, requestClient.getAppConfig());

        DadaApiResponse apiResponse = requestClient.callRpc(requestParam, UrlConstant.CONFIRM_GOODS);

        sbPre.append("update ").append(PojoTables.ORDER_INFO_PRE).append(" set orderStatus = ").append(ORDER_STATUS.POSTMAN_CANT_FINISH).
                append("' where delFlag=0 and orderNo = '").append(orderId).append("'");
        try {
            UserDaoSql.getInstance().executeBySql(sbPre.toString());
        } catch (SQLException e) {
            e.printStackTrace();
        }

        log.info(apiResponse.toString());
        if (apiResponse.getCode() == 0) {
            return AjaxResult.successResult(apiResponse.getResult());
        } else {
            return AjaxResult.errorResult("msg", apiResponse.getMsg());
        }
    }

    /**
     * 订单接受状态回调接口
     * <p>
     * 每次订单状态发生变化时，会对添加订单接口中callback的URL进行回调。
     * <p>
     * 1. 已取消：包括配送员取消、商户取消、客服取消、系统取消（比如：骑士接单后一直未取货）， 此时订单的状态为5，可以通过“重新发单”来下发订单。
     * <p>
     * 2. 妥投异常：配送员在收货地，无法正常送到用户手中（包括用户电话打不通、客户暂时不方便收件、客户拒收、货物有问题等等）
     * <p>
     * 3. 状态1000：表示因为达达内部服务异常，导致下发订单失败。可以通过“新增订单”来下发订单。
     *
     * @param order 实例
     *              {
     *              "signature": "aaaaaaaaaaaaaaaaaa",
     *              "client_id": "270340107542552",
     *              "order_id": "111111111111",
     *              "order_status": 4,
     *              "cancel_reason": "",
     *              "cancel_from": 0,
     *              "dm_id": 1,
     *              "dm_name": "测试",
     *              "dm_mobile": "13100001111",
     *              "finish_code": "8888",
     *              "update_time": 1511789475
     *              }
     * @return {"status":"success","code":0,"msg":"成功","fail":false}
     */
    @RequestMapping(value = "/handle", method = RequestMethod.POST)
    public String handleOrder(@RequestBody String order) {
        UpdateDadaOrderTO updateDadaOrderTO = JSON.parseObject(order, UpdateDadaOrderTO.class);
        String orderId = updateDadaOrderTO.getOrderId();
        StringBuffer sbPre = new StringBuffer();

        OrderInfoPreMemory.getInstance().modifyStatus(orderId);
        //TODO 更新订单状态
        switch (updateDadaOrderTO.getOrderStatus()) {
            case 1: {
                // 待接单
                log.info(orderId + "待接单");
                sbPre.append("update ").append(PojoTables.ORDER_INFO_PRE).append(" set orderStatus = ").append(ORDER_STATUS.POSTMAN_SURE).
                        append(" where delFlag=0 and orderNo = '").append(orderId).append("'");
                try {
                    UserDaoSql.getInstance().executeBySql(sbPre.toString());
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                OrderInfoMemory.getInstance().deleteCache();
                return AjaxResult.successResult("待接单");
            }
            case 2: {
                // 待取货
                log.info(orderId + "待取货");
                sbPre.append("update ").append(PojoTables.ORDER_INFO_PRE).append(" set orderStatus = ").append(ORDER_STATUS.POSTMAN_SURE).
                        append(" where delFlag=0 and orderNo = '").append(orderId).append("'");
                try {
                    UserDaoSql.getInstance().executeBySql(sbPre.toString());
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                OrderInfoMemory.getInstance().deleteCache();
                return AjaxResult.successResult("待取货");
            }
            case 3: {
                // 配送中
                log.info(orderId + "配送中");
                sbPre.append("update ").append(PojoTables.ORDER_INFO_PRE).append(" set orderStatus = ").append(ORDER_STATUS.PEISONG).
                        append(" where delFlag=0 and orderNo = '").append(orderId).append("'");
                try {
                    UserDaoSql.getInstance().executeBySql(sbPre.toString());
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                OrderInfoMemory.getInstance().deleteCache();
                return AjaxResult.successResult("配送中");
            }
            case 4: {
                // 已完成
                log.info(orderId + "已完成");
                sbPre.append("update ").append(PojoTables.ORDER_INFO_PRE).append(" set orderStatus = ").append(ORDER_STATUS.POSTMAN_FINISH).
                        append(" where delFlag=0 and orderNo = '").append(orderId).append("'");
                try {
                    UserDaoSql.getInstance().executeBySql(sbPre.toString());
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                OrderInfoMemory.getInstance().deleteCache();
                return AjaxResult.successResult("已完成");
            }
            case 5: {
                // 已取消

                return AjaxResult.successResult("已取消");
            }
            case 8: {
                //指派单
                log.info(orderId + "指派单");
                sbPre.append("update ").append(PojoTables.ORDER_INFO_PRE).append(" set orderStatus = ").append(ORDER_STATUS.POSTMAN_ZHIDING).
                        append(" where delFlag=0 and orderNo = '").append(orderId).append("'");
                try {
                    UserDaoSql.getInstance().executeBySql(sbPre.toString());
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                OrderInfoMemory.getInstance().deleteCache();
                return AjaxResult.successResult("指派单");
            }
            case 9: {
                // 妥投异常之物品返回中
                log.info(orderId + "妥投异常之物品返回中");
                sbPre.append("update ").append(PojoTables.ORDER_INFO_PRE).append(" set orderStatus = ").append(ORDER_STATUS.POSTMAN_CANT_FINISH).
                        append(" where delFlag=0 and orderNo = '").append(orderId).append("'");
                try {
                    UserDaoSql.getInstance().executeBySql(sbPre.toString());
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                OrderInfoMemory.getInstance().deleteCache();
                return AjaxResult.successResult("妥投异常之物品返回中");
            }
            case 10: {
                // 妥投异常之物品返回完成
                log.info(orderId + "妥投异常之物品返回完成");
                sbPre.append("update ").append(PojoTables.ORDER_INFO_PRE).append(" set orderStatus = ").append(ORDER_STATUS.POSTMAN_CANT_FINISH).
                        append(" where delFlag=0 and orderNo = '").append(orderId).append("'");
                try {
                    UserDaoSql.getInstance().executeBySql(sbPre.toString());
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                OrderInfoMemory.getInstance().deleteCache();
                return AjaxResult.successResult("妥投异常之物品返回完成");
            }
            case 100: {
                // 骑士到店
                log.info(orderId + "骑士到店");

                sbPre.append("update ").append(PojoTables.ORDER_INFO_PRE).append(" set orderStatus = ").append(ORDER_STATUS.POSTMAN_DAODIAN).
                        append(" where delFlag=0 and orderNo = '").append(orderId).append("'");
                try {
                    UserDaoSql.getInstance().executeBySql(sbPre.toString());
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                OrderInfoMemory.getInstance().deleteCache();
                return AjaxResult.successResult("骑士到店");
            }
            case 1000: {
                // 创建达达运单失败
                log.info(orderId + "创建达达运单失败");

                return AjaxResult.successResult("创建达达运单失败");
            }
            default: {
                return AjaxResult.successResult("订单状态错误");
            }
        }
    }

}
